#include "EventSystem.h"
void CEventSystem::RegisterClient(EVENTID eventID, IListener* pClient)
{
	if(!pClient || AlreadyRegistered(eventID, pClient))return;
	m_ClientDatabase.insert(make_pair(eventID, pClient));
}

void CEventSystem::UnregisterClient(EVENTID eventID, IListener* pClient)
{
	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;

	range = m_ClientDatabase.equal_range(eventID);
	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{
		if((*mmIter).second == pClient)
		{
			mmIter = m_ClientDatabase.erase(mmIter);
			break;
		}
	}
}

void CEventSystem::UnregisterClientAll(IListener *pClient)
{
	multimap<string, IListener*>::iterator mmIter = m_ClientDatabase.begin();

	while(mmIter !=m_ClientDatabase.end())
	{
		if((*mmIter).second == pClient)
		{
			mmIter = m_ClientDatabase.erase(mmIter);
		}
		else
			mmIter++;
	}
}

void CEventSystem::DispatchEvent(CNEvent *pEvent)
{
	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;
	range = m_ClientDatabase.equal_range(pEvent->GetEventID());

	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{
		(*mmIter).second->HandleEvent(pEvent);
	}
}

bool CEventSystem::AlreadyRegistered(EVENTID eventID, IListener* pClient)
{
	bool bIsAlreadyRegistered = false;
	pair<multimap<EVENTID, IListener*>::iterator,
		 multimap<EVENTID, IListener*>::iterator> range;
	range = m_ClientDatabase.equal_range(eventID);
	for(multimap<EVENTID, IListener*>::iterator mmIter = range.first;
					mmIter != range.second; mmIter++)
	{
		if((*mmIter).second == pClient)
		{
			bIsAlreadyRegistered = true;
			break;
		}
	}
	return bIsAlreadyRegistered;
}

bool CEventSystem::HasEventTriggered( EVENTID eventID )
{
	list<CNEvent>::iterator iter = m_CurrentEvents.begin();
	for( ; iter != m_CurrentEvents.end(); ++iter )
		if( (*iter).GetEventID() == eventID )
			return true;
	return false;
}

void CEventSystem::SendEvent(EVENTID eventID, void* pData)
{
	CNEvent newEvent(eventID, pData);

	m_CurrentEvents.push_back(newEvent);
}

void CEventSystem::SendUniqueEvent( EVENTID eventID, void* pData )
{
	if(HasEventTriggered(eventID))
		return;
	SendEvent( eventID, pData );
}

void CEventSystem::ProcessEvents(void)
{
	while(m_CurrentEvents.size())
	{
		DispatchEvent(&m_CurrentEvents.front());
		m_CurrentEvents.pop_front();
	}
}

void CEventSystem::ClearEvents(void)
{
	m_CurrentEvents.clear();
}

void CEventSystem::ShutdownEventSystem(void)
{
	m_ClientDatabase.clear();
}